/**
 * 如何进行组件通信
 * ？父向子 组件通信 props
 * ？子向父 组件通信 emit
 * ？以父组件为中转 两个子组件互相通信 emit -> setState -> props
 * ？多层级组件通信 Provider/Consumer (类似Vue3 provide/inject)
 */

import React from "react"
// const { Consumer } = createContext()
import { Consumer } from '../../App' // 需要引入与Provider相同定义的createContext()中的Consumer

class Parent extends React.Component {
  state = {
    msgA: '这是A信息',
    msgB: '这是B信息',
    list: [1, 2, 3], // 数组
    info: { name: 'dg', age: 18 } // 对象
  }
  // 方法
  getMsgInfo = () => {
    console.log(this.state.msgA)
  }
  // 获取子组件的数据（子组件向父组件传值）
  getChildMsg = (info) => {
    // 此处得到组件B的传值，改变了msgA，进而改变了父组件向组件A的传值
    /**
     * 以父组件做中转，得到B的值再传给A，通过该方法实现 两子组件间的通信
     */
    this.setState({
      msgA: info
    })
  }
  render () {
    return (
      <>
        <div>我是父组件：{this.state.msgA}</div>
        <br />
        <ChildA msg={this.state.msgA} />
        <br />
        <ChildB msg={this.state.msgB}
          list={this.state.list}
          info={this.state.info}
          getMsgInfo={this.getMsgInfo}
          getChildMsg={this.getChildMsg}
          /** 传递jsx模板,类似vue的slot插槽语法  */
          template={<h1>这是一段jsx模板语法</h1>} />
      </>
    )
  }
}

function ChildA (props) {
  // props绑定了所有传值的数据
  return (
    <div>我是函数子组件A,来自父组件信息：{props.msg}</div>
  )
}

class ChildB extends React.Component {
  // props默认参数
  // 可以使用props-type插件判断类型 (偷懒没搞)
  static defaultProps = {
    msg: '17点14分'
  }
  state = {
    msg: '我是子组件B中的数据'
  }
  render () {
    return (
      // 使用this关键字获取props
      <div>
        <Consumer>
          {value => <h2>{value.PLAT_FORM}</h2>}
        </Consumer>
        <br />
        我是类子组件B,来自父组件信息：{this.props.msg}
        <div>
          <button onClick={this.props.getMsgInfo}>触发props中的方法</button>
        </div>
        <div>{this.props.template}</div>
        <div>
          <button onClick={() => this.props.getChildMsg(this.state.msg)}>触发子组件向父组件传值</button>
        </div>
      </div>
    )
  }
}

export default Parent